﻿using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;

namespace Sgr.BackGroundTasks
{
    /// <summary>
    /// 使用 Invoker (IBackGroundTaskInvoker) 的统一执行器。
    /// 说明：
    /// 1. 调度端只需提供 TaskClassType（用于生成 key：类型 FullName），以及可选 TaskData。
    /// 2. 不再反射方法 / 不再区分有参和无参逻辑，全部通过 Invoker 屏蔽。
    /// 3. 若后续要加入拦截（性能、重试统计、指标），可以对 IBackGroundTaskInvoker 做 Decorator。
    /// </summary>
    public class DefaultBackGroundTaskExecutor : IBackGroundTaskExecutor
    {
        private readonly ILogger<DefaultBackGroundTaskExecutor> _logger;

        public DefaultBackGroundTaskExecutor(ILogger<DefaultBackGroundTaskExecutor> logger)
        {
            _logger = logger ?? throw new ArgumentNullException(nameof(logger));
        }

        public async Task ExecuteAsync(BackGroundTaskContext context, CancellationToken cancellationToken = default)
        {
            Check.NotNull(context, nameof(context));
            Check.NotNull(context.ServiceProvider, nameof(context.ServiceProvider));
            Check.NotNull(context.TaskClassType, nameof(context.TaskClassType));

            var key = context.TaskClassType.AssemblyQualifiedName ?? throw new BackGroundTaskException("任务类型 FullName 为空，无法作为 Key。");

            _logger.LogDebug("开始执行后台任务：{TaskType}", context.TaskClassType.FullName);

            var invoker = context.ServiceProvider.GetKeyedService<IBackGroundTaskInvoker>(key)
               ?? throw new BackGroundTaskException($"未找到后台任务 Invoker：Key={key}");

            try
            {
                await invoker.InvokeAsync(context.TaskData, cancellationToken).ConfigureAwait(false);
                _logger.LogDebug("后台任务执行完成 Key={Key}", key);
            }
            catch (BackGroundTaskException)
            {
                throw;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "后台任务执行失败 Key={Key}", key);
                throw new BackGroundTaskException($"后台任务执行失败：{ex.Message}", ex);
            }
        }
    }
}